package com.nlscan.qdkit.ui.publico.util;

import java.util.Random;

public class DataUtil {
    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    //����ģʽ
    private volatile static DataUtil singleton;

    /**
     * ��ȡʵ��
     */
    public static DataUtil getInstanse() {
        if (singleton == null) {
            synchronized (DataUtil.class) {
                if (singleton == null) {
                    singleton = new DataUtil();
                }
            }
        }
        return singleton;
    }

    /**
     * byteת��Ϊint(������������������)
     */
    public int bytes2int(byte[] b) {
        // 0xff�Ķ����Ʊ�ʾΪ: 1111 1111
        int mask = 0xff;
        int temp = 0;
        int res = 0;
        for (int i = 0; i < 4; i++) {
            res <<= 8;// ����8λ����ʲô��˼?
            temp = b[3 - i] & mask;
            res |= temp;
        }
        return res;
    }

    public byte[] int2bytes(int num) {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (num >>> (24 - i * 8));
        }
        return b;
    }

    public int bytes2int(byte[] b, int len) {
        int mask = 0xff;
        int temp = 0;
        int res = 0;
        for (int i = 0; i < len; i++) {
            res <<= 8;
            temp = b[len - i] & mask;
            res |= temp;
        }
        return res;
    }

    // ת���ֽ���
    public int ChangeIndex(int num) {
        byte[] test = new byte[4];
        test[0] = (byte) (num & 0x000000FF);
        test[1] = (byte) (num & 0x0000FF00 >> 8);
        test[2] = (byte) (num & 0x00FF0000 >> 16);
        test[3] = (byte) ((num & 0xFF000000) >> 24);
        return bytes2int(test);
    }

    public int random() {
        Random r = new Random();
        return r.nextInt();
    }

    public int ntohl(int in) {
        return ((in & 0xFF) << 24) | ((in & 0xFF00) << 8) | ((in & 0xFF0000) >> 8) | (
                (in & 0xFF000000) >> 24);
    }

    byte[] htonl(int i) {
        byte[] sReturn = new byte[4];
        sReturn[0] = (byte) ((i >> 24) & 0xFF);
        sReturn[1] = (byte) ((i >> 16) & 0xFF);
        sReturn[2] = (byte) ((i >> 8) & 0xFF);
        sReturn[3] = (byte) ((i) & 0xFF);
        return sReturn;
    }

    public byte[] long2bytes(long num) {
        byte[] b = new byte[8];
        for (int i = 0; i < 8; i++) {
            b[i] = (byte) (num >>> (56 - i * 8));
        }
        byte[] bReturn = new byte[8];
        bReturn[0] = b[7];
        bReturn[1] = b[6];
        bReturn[2] = b[5];
        bReturn[3] = b[4];
        bReturn[4] = b[3];
        bReturn[5] = b[2];
        bReturn[6] = b[1];
        bReturn[7] = b[0];
        return bReturn;
    }

    /**
     * �������
     */
    public byte[] ChangeByteOrder(byte[] b, int iLen) {
        byte[] bTest = new byte[iLen];
        for (int i = 0; i < iLen; i++) {
            bTest[i] = b[iLen - i - 1];
        }
        return bTest;
    }

    public long byte2long(byte[] b) {
        int shift;
        long kk, jj = 0;
        shift = 0;
        for (int i = 0; i < 8; i++) {
            kk = (b[i]);
            if (kk < 0) kk = 256 + kk;
            kk = (kk << shift);
            jj = jj + kk;
            shift = shift + 8;
        }
        return jj;
    }

    public long byte2longB(byte buf[], int start, int len) {
        long ret = 0;
        len = len > 4 ? 4 : len;
        ret |= (buf[start] & 0x80);
        ret |= (buf[start] & 0x7F);
        for (int i = 1; i < len; i++) {
            ret |= ((buf[start + i] & 0x80) << (8 * i));
            ret |= ((buf[start + i] & 0x7F) << (8 * i));
        }
        return ret;
    }

    public long byteFuckLong(byte[] b) {
        long lReturn = 0;
        long lmask = 1;
        for (int i = 0; i < 64; i++) {
            if (b[i] == 1) {
                lReturn += (lmask << i);
            }
        }
        return lReturn;
    }

    public short bytes2short(byte[] b) {
        short mask = 0xff;
        short temp = 0;
        short res = 0;
        for (int i = 0; i < 2; i++) {
            res <<= 8;
            temp = (short) (b[1 - i] & mask);
            res |= temp;
        }
        return res;
    }

    public byte[] short2bytes(short data) {
        byte bytes[] = new byte[2];

        bytes[0] = (byte) ((data & 0xff00) >> 8);
        bytes[1] = (byte) (data & 0x00ff);
        return bytes;
    }

    /**
     * ת����16���Ƶ��ַ���
     */
    public String getHexString(byte[] b) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            if (i % 4 == 0) {
                str.append(" " + hex.toUpperCase());
            } else {
                str.append(hex.toUpperCase());
            }
        }
        return str.toString();
    }

    public static String bytesToHex(byte[] bytes) {
        char[] buf = new char[bytes.length * 2];
        int index = 0;
        for (byte b : bytes) { // 利用位运算进行转换，可以看作方法一的变种
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }

        return new String(buf);
    }


    public static byte[] hextoBytes(String str) {
        if (str == null || str.trim().equals("")) {
            return new byte[0];
        }

        byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }

        return bytes;
    }

    //将byte转换为一个长度为8的byte数组，数组每个值代表bit
    public static byte[] getBooleanArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 0; i < 8; i++) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }

    public static byte setBooleanArray(byte[] input) {
        byte b = 0x00;
        for (int i = 0; i < 8; i++) {
            b = (byte) (b << 1);
            b = (byte) (b | (input[7 - i] & 1));
        }
        return b;
    }

    public static boolean getLongState(long input, int index) {
        return (input & (1L << index)) > 0;
    }

    public static long setLongState(long input, int index, boolean enable) {
        if (enable) {
            return input | (1L << index);
        } else {
            return input & (~(1L << index));
        }
    }

    public static long longFrom8Bytes(byte[] input, int offset, boolean littleEndian) {
        long value = 0;
        // 循环读取每个字节通过移位运算完成long的8个字节拼装
        for (int count = 0; count < 8; ++count) {
            int shift = (littleEndian ? count : (7 - count)) << 3;
            value |= ((long) 0xff << shift) & ((long) input[offset + count] << shift);
        }
        return value;
    }

    public static long longFrom4Bytes(byte[] input, int offset, boolean littleEndian) {
        long value = 0;
        // 循环读取每个字节通过移位运算完成long的8个字节拼装
        for (int count = 0; count < 4; ++count) {
            int shift = (littleEndian ? count : (7 - count)) << 3;
            value |= ((long) 0xff << shift) & ((long) input[offset + count] << shift);
        }
        return value;
    }
}
